/*
// http://caml.inria.fr/pub/ml-archives/caml-list/2006/11/6aa4538ddc5b63c8da84195ff061198d.fr.html

// data T f = Bool (f Bool) | Int (f Int) | Fun (T (F1 f))
sealed trait T[f[_]]
case class TBoolean[f[_]](x: f[Boolean]) extends T[f]

// class Dynamic t where
//     inj :: f t -> T f
//     prj :: T f -> Maybe (f t)
trait DynamicInj[t] {
  val self: f[t]
  def inj[f[_]]: T[f]
}

trait DynamicPrj[t] {
  val self: T[f]
  def prj[f[_]]: Option[f[t]]
}

// instance Dynamic Bool where
//     inj = Bool
//     prj (Bool x) = Just x
//     prj _ = Nothing
implicit def InjectBoolean[f[_]](x: f[Boolean]): T[f] = TBoolean[f](x)
implicit def ProjectBoolean[f[_]](x: T[f]): Option[f[Boolean]] = x match { 
    case TBoolean(x) => Some(x) 
    case _ => None
  }

// 
// instance Dynamic Int where
//     inj = Int
//     prj (Int x) = Just x
//     prj _ = Nothing


// newtype F1 f a = F1 { f1 :: T (F2 f a) }
// newtype F2 f a b = F2 { f2 :: f (a -> b) }
type F1[f[_], a] = T[]
type F2[f[_], a, b] = f[a => b]


// instance (Dynamic a, Dynamic b) => Dynamic (a -> b) where
//     inj x = Fun (inj (F1 (inj (F2 x))))
//     prj (Fun t) = prj t >>= prj . f1 >>= return . f2
//     prj _ = Nothing

*/